package main

import (
	"api-demo/model"
	"fmt"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

type _EntityRoutes struct {
	getAll     bool
	getById    bool
	insert     bool
	updateById bool
	drop       bool
}

func newEntityRoutes[T any](path string, routes _EntityRoutes) {
	if !routes.getAll {
		_GET(path, func(ctx *gin.Context) {
			var result []T
			model.DB.Find(&result)
			ctx.JSON(http.StatusOK, result)
		})
	}

	if !routes.getById {
		_GET(path+"/:id", func(ctx *gin.Context) {
			id, ok := getId(ctx)
			if !ok {
				return
			}

			var result T
			res := model.DB.First(&result, id)
			if res.RowsAffected == 1 {
				ctx.JSON(http.StatusOK, result)
			} else {
				fmt.Println("RowsAffected", res.RowsAffected)
				ctx.JSON(http.StatusNotFound, nil)
			}
		})
	}

	if !routes.insert {
		_POST(path, func(ctx *gin.Context) {
			var data T
			ctx.BindJSON(&data)
			model.DB.Create(&data)
			ctx.JSON(http.StatusOK, nil)
		})
	}

	if !routes.updateById {
		_POST(path+"/:id", func(ctx *gin.Context) {
			id, ok := getId(ctx)
			if !ok {
				return
			}

			var data T
			ctx.BindJSON(&data)
			var temp T
			result := model.DB.Model(&temp).Where("id=?", id).Updates(data)
			if result.RowsAffected == 1 {
				ctx.JSON(http.StatusOK, nil)
			} else {
				ctx.JSON(http.StatusBadRequest, nil)
			}
		})
	}

	if !routes.drop {
		_DELETE(path+"/:id", func(ctx *gin.Context) {
			id, ok := getId(ctx)
			if !ok {
				return
			}

			var temp T
			result := model.DB.Delete(&temp, id)
			if result.RowsAffected == 1 {
				ctx.JSON(http.StatusOK, nil)
			} else {
				ctx.JSON(http.StatusBadRequest, nil)
			}
		})
	}
}

func getId(ctx *gin.Context) (int, bool) {
	idStr, ok := ctx.Params.Get("id")
	if !ok {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"message": "没有 id",
		})
		return 0, false
	}

	id, err := strconv.Atoi(idStr)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"message": "id 格式不正确",
		})
		return 0, false
	}

	return id, true
}
